package utils;

import com.alibaba.fastjson.JSONObject;
import entity.BodyParts;
import entity.ResponseData;

import java.net.URLEncoder;
import java.util.ArrayList;

/**
 * 根究返回的JSON数据判断图片中的人是否摔倒
 */
public class FallDetectionUtils {

    /**
     *  根据人体坐标判断是否摔倒
     * @param top_head_x    头顶X轴坐标
     * @param top_head_y    头顶Y轴坐标
     * @param left_ankle_x  左脚踝X轴坐标
     * @param left_ankle_y  左脚踝Y轴坐标
     * @param right_ankle_x 右脚踝X轴坐标
     * @param right_ankle_y 右脚踝Y轴坐标
     * @return true为摔倒 false为未摔倒
     */
    public static boolean isFall(double top_head_x,double top_head_y,
                                     double left_ankle_x,double left_ankle_y,
                                     double right_ankle_x,double right_ankle_y){
        //  计算两个脚踝的中间点坐标
        //  中间点X轴坐标
        double middle_point_x = (left_ankle_x+right_ankle_x)/2;
        //  中间点Y轴坐标
        double middle_point_y = (left_ankle_y+right_ankle_y)/2;

        //  如果头比脚低
        if (top_head_y<middle_point_y){
            System.out.println("头比脚低！");
            return true;
        }

        //  如果垂直，认定为站立状态
        if (top_head_x == middle_point_x){
            return false;
        }

        //  计算头顶与中间点的连线与水平方向的夹角
        //  正切值
        double temp = Math.abs(top_head_y - middle_point_y)/Math.abs(top_head_x - middle_point_x);
        //  计算出角度
        double angle = Math.toDegrees(Math.atan(temp));
        System.out.println(angle);
        if (angle > 45.0){
            return false;
        }else{
            return true;
        }
    }


    /**
     * 批量摔倒检测
     * @param path 测试目录文件夹的本地位置
     */
    public static void detectByDirectory(String path){
        //  定义的临时变量，用来记录有几张图片是摔倒的
        int temp = 0;
        // 请求url
        String url = "https://aip.baidubce.com/rest/2.0/image-classify/v1/body_analysis";
        ArrayList<String> fileNames = new ArrayList<>();
        //  获取文件夹目录下的所有图片名称
        FileUtil.getAllFileName(path,fileNames);
        for (String fileName : fileNames) {
            //  获取图片的相对路径
            String filePath = path+"\\"+fileName;

            try {
                byte[] imgData = FileUtil.readFileByBytes(filePath);
                String imgStr = Base64Util.encode(imgData);
                String imgParam = URLEncoder.encode(imgStr, "UTF-8");

                String param = "image=" + imgParam;

                // 注意这里仅为了简化编码每一次请求都去获取access_token，线上环境access_token有过期时间， 客户端可自行缓存，过期后重新获取。
                String accessToken = "24.9eeb2842c1d2c6000e48c524aae4922e.2592000.1629264825.282335-24569897";

                //  单张图片的检测返回结果
                Thread.sleep(500);
                String result = HttpUtil.post(url, accessToken, param);

                //  将JSON字符串序转换成对象
                ResponseData responseData = JSONObject.parseObject(result, ResponseData.class);
                //  拿到相应坐标
                BodyParts bodyParts = responseData.getPersonInfo()[0].getBodyParts();
                double top_head_x = bodyParts.getTop_head().getX();
                double top_head_y = -bodyParts.getTop_head().getY();
                double left_ankle_x = bodyParts.getLeft_ankle().getX();
                double left_ankle_y = -bodyParts.getLeft_ankle().getY();
                double right_ankle_x = bodyParts.getRight_ankle().getX();
                double right_ankle_y = -bodyParts.getRight_ankle().getY();
                boolean isFall = FallDetectionUtils.isFall(top_head_x, top_head_y, left_ankle_x, left_ankle_y, right_ankle_x, right_ankle_y);
                if (isFall == true){
                    System.out.println(filePath+"中的人可能摔倒了！");
                    temp++;
                }else {
                    System.out.println(filePath+"中的人应该没有摔倒！！");
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        System.out.println("一种有"+temp+"张图片识别出来是摔倒的!");

    }


    /**
     *
     * @param filePath 单张图片的本地路径
     * @return true为摔倒，false为为摔倒
     */
    public static boolean detectOnePhoto(String filePath){
        // 请求url
        String url = "https://aip.baidubce.com/rest/2.0/image-classify/v1/body_analysis";

        try {
            byte[] imgData = FileUtil.readFileByBytes(filePath);
            String imgStr = Base64Util.encode(imgData);
            String imgParam = URLEncoder.encode(imgStr, "UTF-8");

            String param = "image=" + imgParam;

            // 注意这里仅为了简化编码每一次请求都去获取access_token，线上环境access_token有过期时间， 客户端可自行缓存，过期后重新获取。
            String accessToken = "24.9eeb2842c1d2c6000e48c524aae4922e.2592000.1629264825.282335-24569897";

            //  单张图片的检测返回结果
            Thread.sleep(500);
            String result = HttpUtil.post(url, accessToken, param);

            //  将JSON字符串序转换成对象
            ResponseData responseData = JSONObject.parseObject(result, ResponseData.class);
            //  拿到相应坐标
            BodyParts bodyParts = responseData.getPersonInfo()[0].getBodyParts();
            double top_head_x = bodyParts.getTop_head().getX();
            double top_head_y = -bodyParts.getTop_head().getY();
            double left_ankle_x = bodyParts.getLeft_ankle().getX();
            double left_ankle_y = -bodyParts.getLeft_ankle().getY();
            double right_ankle_x = bodyParts.getRight_ankle().getX();
            double right_ankle_y = -bodyParts.getRight_ankle().getY();
            boolean isFall = FallDetectionUtils.isFall(top_head_x, top_head_y, left_ankle_x, left_ankle_y, right_ankle_x, right_ankle_y);
            //  摔倒了
            if (isFall == true){
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        //  没摔倒
        return false;
    }
}
